package com.jhgsys.internal.sypq.utils;

import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.*;

import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @description:
 * @author: lucas
 * @date: 2024/11/24 17:35
 */
@Slf4j
public class WordUtils {


    /**
     * 根据指定的参数值、模板，生成 word 文档
     *
     * @param param       需要替换的变量
     * @param inputStream 模板
     */
    public static void generateWord(Map<String, Object> param, InputStream inputStream, String directoryName, String fileName, boolean isPdf) {
        try {
            OPCPackage pack = OPCPackage.open(inputStream);
            XWPFDocument doc = new XWPFDocument(pack);

            // 处理段落
            List<XWPFParagraph> paragraphList = doc.getParagraphs();
            processParagraphs(paragraphList, param, doc);

            // 处理表格
            Iterator<XWPFTable> it = doc.getTablesIterator();
            while (it.hasNext()) {
                XWPFTable table = it.next();
                List<XWPFTableRow> rows = table.getRows();
                for (XWPFTableRow row : rows) {
                    List<XWPFTableCell> cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        List<XWPFParagraph> paragraphListTable = cell.getParagraphs();
                        processParagraphs(paragraphListTable, param, doc);
                    }
                }
            }

//            String filePath = directoryName + "/" + fileName + ".docx";
            String filePath = directoryName + "/" + fileName;
            OutputStream out = new FileOutputStream(new File(filePath));
            doc.write(out);
            out.flush();
            out.close();
            //word转pdf
            if(isPdf){
                String pdfFileName = fileName.substring(0, fileName.lastIndexOf(".")) + ".pdf";
                String pdfFilePath = directoryName + "/" + pdfFileName;
                ByteArrayOutputStream b = new ByteArrayOutputStream();
                XWPFDocument docx = new XWPFDocument(new FileInputStream(filePath));
                docx.write(b);
                InputStream docxInputStream = new ByteArrayInputStream(b.toByteArray());
                IConverter converter = LocalConverter.builder().build();
                boolean execute = converter.convert(docxInputStream).as(DocumentType.DOCX).to(new FileOutputStream(pdfFilePath)).as(DocumentType.PDF).schedule().get();
                b.close();
                docxInputStream.close();
            }

        } catch (Exception e) {
            log.error("错误信息:{},{}", e.getStackTrace(), e);
        }
    }


    /**
     * 处理段落
     *
     * @param paragraphList
     * @throws FileNotFoundException
     * @throws InvalidFormatException
     */
    public static void processParagraphs(List<XWPFParagraph> paragraphList, Map<String, Object> param, XWPFDocument doc)
            throws InvalidFormatException, FileNotFoundException {

        if (paragraphList != null && paragraphList.size() > 0) {
            for (XWPFParagraph paragraph : paragraphList) {
                List<XWPFRun> runs = paragraph.getRuns();
                String text = "", color = "";
                for (XWPFRun run : runs) {
                    try {
                        String t = run.getText(0);
                        if (t != null) {
                            color = run.getColor();
                            text += t;
                        }
                    } catch (Exception e) {
                        log.info(e.toString());
                    }

                }
                if (StringUtils.isNotEmpty(text)) {
                    boolean isSetText = false;
                    Boolean flag = true;
                    for (Map.Entry<String, Object> entry : param.entrySet()) {
                        String key = entry.getKey();
                        key = "$" + key;
                        if (text.indexOf(key) != -1) {
                            isSetText = true;
                            flag = false;
                            Object value = entry.getValue();
                            if (value != null) {
                                text = text.replace(key, value.toString());
                            } else {
                                text = text.replace(key, "-");
                            }
                        }
                    }
                    //说明map中没有模板的key  默认为空
                    if (flag && text.startsWith("$")) {
                        isSetText = true;
                        //若value为空，组装""
                        text = text.replace(text, "");
                    }
                    if (isSetText) {
                        String[] split = text.split("\n");
                        runs.get(0).setText(split[0], 0);
                        if (split.length > 1) {
                            paragraph.setAlignment(ParagraphAlignment.LEFT);
                            for (int i = 1; i < split.length; i++) {
                                XWPFRun run = paragraph.createRun();
                                run.addBreak();
                                run.setText(split[i]);
                            }
                            for (int i = 1; i < runs.size(); i++) {
                                runs.get(1).setText("", 0);
                            }
                        } else {
                            for (int i = 1; i < runs.size(); i++) {
                                runs.get(i).setText("", 0);
                            }
                        }

                        if (StringUtils.isNotEmpty(color)) {
                            runs.get(0).setColor(color);
                        }

                    }
                }
            }
        }
    }

    /**
     * 删除目录
     * @param filePath
     * @return
     */
    public static boolean deleteFile(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            return false;
        }
        if (file.isFile()) {
            return file.delete();
        }
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.isFile()) {
                if (!f.delete()) {
                    System.out.println(f.getAbsolutePath() + " delete error!");
                    return false;
                }
            } else {
                if (!deleteFile(f.getAbsolutePath())) {
                    return false;
                }
            }
        }
        return file.delete();
    }

}
